﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System;
using Tesla.Scene;

namespace Tesla.Content.Loaders {

    /// <summary>
    /// Base class for all Assimp-based model loaders.
    /// </summary>
    public abstract class BaseAssimpLoader : ResourceLoader<Spatial> {

        private AssimpTranslator m_translator;

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseAssimpLoader"/> class.
        /// </summary>
        /// <param name="formatExtension">The format extension.</param>
        public BaseAssimpLoader(String formatExtension) : base(formatExtension) { }

        /// <summary>
        /// Called when the loader is initialized by the content manager.
        /// </summary>
        protected override void OnInitialize() {
            m_translator = new AssimpTranslator(base.ContentManager);
        }

        /// <summary>
        /// Loads the specified resource.
        /// </summary>
        /// <param name="resource">The resource to load</param>
        /// <param name="parameters">Loader parameters</param>
        /// <returns>The loaded resource</returns>
        public override Spatial Load(IResource resource, LoaderParameters parameters) {
            ModelLoaderParameters modelParams = parameters as ModelLoaderParameters;
            if(modelParams == null) {
                modelParams = new ModelLoaderParameters();
            }

            return m_translator.Load(resource, base.Extension, modelParams);
        }
    }

    /// <summary>
    /// Loader for the waveFront .obj model format.
    /// </summary>
    public sealed class OBJLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="OBJLoader"/> class.
        /// </summary>
        public OBJLoader() : base(".obj") { }

    }

    /// <summary>
    /// Loader for the collada .dae model format.
    /// </summary>
    public sealed class ColladaLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="ColladaLoader"/> class.
        /// </summary>
        public ColladaLoader() : base(".dae") { }

    }

    /// <summary>
    /// Loader for the blender .blend model format.
    /// </summary>
    public sealed class BlenderLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="BlenderLoader"/> class.
        /// </summary>
        public BlenderLoader() : base(".blend") { }

    }

    /// <summary>
    /// Loader for the DirectX .x model format.
    /// </summary>
    public sealed class XLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="XLoader"/> class.
        /// </summary>
        public XLoader() : base(".x") { }

    }

    /// <summary>
    /// Loader for AutoCad's .dxf model format.
    /// </summary>
    public sealed class DXFLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="DXFLoader"/> class.
        /// </summary>
        public DXFLoader() : base(".dxf") { }

    }

    /// <summary>
    /// Loader for Milkshape 3D's .ms3d model format.
    /// </summary>
    public sealed class MilkshapeLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="MilkshapeLoader"/> class.
        /// </summary>
        public MilkshapeLoader() : base(".ms3d") { }

    }

    /// <summary>
    /// Loader for the 3Ds Max .ase model format.
    /// </summary>
    public sealed class ASELoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="ASELoader"/> class.
        /// </summary>
        public ASELoader() : base(".ase") { }

    }

    /// <summary>
    /// Loader for the 3ds Max .3ds model format.
    /// </summary>
    public sealed class Max3DSLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="Max3DSLoader"/> class.
        /// </summary>
        public Max3DSLoader() : base(".3ds") { }

    }

    /// <summary>
    /// Loader for the AC3D .ac model format.
    /// </summary>
    public sealed class AC3DLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="AC3DLoader"/> class.
        /// </summary>
        public AC3DLoader() : base(".ac") { }

    }

    /// <summary>
    /// Loader for the Stanford Polygon Library .ply model format.
    /// </summary>
    public sealed class StanfordPolygonLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="StanfordPolygonLoader"/> class.
        /// </summary>
        public StanfordPolygonLoader() : base(".ply") { }

    }

    /// <summary>
    /// Loader for the Ogre XML model format.
    /// </summary>
    public sealed class OgreXmlLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="OgreXmlLoader"/> class.
        /// </summary>
        public OgreXmlLoader() : base(".xml") { }

    }

    /// <summary>
    /// Loader for the Irrlicht .irrmesh model format.
    /// </summary>
    public sealed class IrrlichtMeshLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="IrrlichtMeshLoader"/> class.
        /// </summary>
        public IrrlichtMeshLoader() : base(".irrmesh") { }

    }

    /// <summary>
    /// Loader for the Irrlicht .irr scene format.
    /// </summary>
    public sealed class IrrlichtSceneLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="IrrlichtSceneLoader"/> class.
        /// </summary>
        public IrrlichtSceneLoader() : base(".irr") { }

    }

    /// <summary>
    /// Loader for the Quake 1 .mdl model format.
    /// </summary>
    public sealed class MDLLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="MDLLoader"/> class.
        /// </summary>
        public MDLLoader() : base(".mdl") { }

    }

    /// <summary>
    /// Loader for the Quake 2 .md2 model format.
    /// </summary>
    public sealed class MD2Loader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="MD2Loader"/> class.
        /// </summary>
        public MD2Loader() : base(".md2") { }

    }

    /// <summary>
    /// Loader for the Quake 3 .md3 model format.
    /// </summary>
    public sealed class MD3Loader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="MD3Loader"/> class.
        /// </summary>
        public MD3Loader() : base(".md3") { }

    }

    /// <summary>
    /// Loader for the Doom 3 .md5 model format.
    /// </summary>
    public sealed class MD5Loader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="MD5Loader"/> class.
        /// </summary>
        public MD5Loader() : base(".md5") { }

    }

    /// <summary>
    /// Loader for the Quake 3 Map/BSP .pk3 scene format.
    /// </summary>
    public sealed class PK3Loader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="PK3Loader"/> class.
        /// </summary>
        public PK3Loader() : base(".pk3") { }

    }

    /// <summary>
    /// Loader for the Valve .smd model format.
    /// </summary>
    public sealed class SMDLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="SMDLoader"/> class.
        /// </summary>
        public SMDLoader() : base(".smd") { }

    }

    /// <summary>
    /// Loader for the Valve .vta model format.
    /// </summary>
    public sealed class VTALoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="VTALoader"/> class.
        /// </summary>
        public VTALoader() : base(".vta") { }

    }

    /// <summary>
    /// Loader for the BlitzBasic 3D .b3d model format.
    /// </summary>
    public sealed class B3DLoader : BaseAssimpLoader {

        /// <summary>
        /// Initializes a new instance of the <see cref="B3DLoader"/> class.
        /// </summary>
        public B3DLoader() : base(".b3d") { }

    }
}
